#import "DetailFragmentPlatformView.h"
#import "FlutterPanglePlugin.h"
#import <Flutter/Flutter.h>
#import <PAGSShortPlay/PAGSShortPlay.h>

@class DetailFragmentDelegateWrapper;

@interface PAGSDetailFragment (DelegateOptional)
- (void)setDelegate:(nullable id<PAGSDetailFragmentDelegate, PAGSAdDelegate>)delegate;
- (void)updateDelegate:(nullable id<PAGSDetailFragmentDelegate, PAGSAdDelegate>)delegate;
@end

@interface DetailFragmentPlatformView ()
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, strong) PAGSDetailFragment *detailFragment;
@property (nonatomic, strong) FlutterEventChannel *eventChannel;
@property (nonatomic, strong) FlutterMethodChannel *methodChannel;
@property (nonatomic, strong) FlutterEventSink eventSink;
@property (nonatomic, assign) BOOL shouldAutoPlay;
@property (nonatomic, assign) BOOL playSingleItemMode;
@property (nonatomic, assign) BOOL hasSetCurrentFragment;
@property (nonatomic, assign) int64_t viewId;
@property (nonatomic, strong, nullable) NSNumber *pendingSeekSeconds;
@property (nonatomic, strong, nullable) NSNumber *pendingStartIndex;
@property (nonatomic, strong, nullable) NSNumber *pendingSetCurrent;
@property (nonatomic, assign) BOOL pendingPlayRequest;
@property (nonatomic, assign) BOOL pendingPauseRequest;
@property (nonatomic, assign) BOOL destroyed;
@property (nonatomic, strong) DetailFragmentDelegateWrapper *delegateWrapper;
@end

@interface DetailFragmentPlatformView (DelegateHandlers)
- (BOOL)handleShortPlay:(PAGSShort *)shortPlay needBlockAtIndex:(int)index;
- (void)handleShortPlay:(PAGSShort *)shortPlay showAdIfNeedAtIndex:(int)index unlockListener:(PAGSPlayBlockResultListener *)listener;
- (void)handleShortPlay:(PAGSShort *)shortPlay playStartIndex:(int)index;
- (void)handleShortPlay:(PAGSShort *)shortPlay itemSelectedWithPosition:(NSInteger)position type:(PAGSFragmentItemType)type;
- (BOOL)handlePlayFailed:(NSError *)error;
- (void)handleShortPlay:(PAGSShort *)shortPlay playStateChanged:(PAGSPlayBackState)state index:(int)index;
- (void)handleShortPlay:(PAGSShort *)shortPlay loadStateDidChanged:(PAGSLoadState)loadState index:(int)index;
- (void)handleShortPlay:(PAGSShort *)shortPlay progressChanged:(long)currentPlayTime duration:(long)duration index:(int)index;
- (void)handleShortPlay:(PAGSShort *)shortPlay playFinishAtIndex:(int)index;
- (void)handleShortPlayEnterImmersiveMode:(PAGSShort *)shortPlay;
- (void)handleShortPlayExitImmersiveMode:(PAGSShort *)shortPlay;
- (void)handleShortPlay:(PAGSShort *)shortPlay onVideoInfoFetched:(PAGSPlayerInfo *)info index:(int)index;
- (void)handleShortPlayDestroy:(PAGSShort *)shortPlay;
- (void)handleOverScroll:(PAGSScrollEvent)position;
@end

@interface DetailFragmentDelegateWrapper : NSObject <PAGSDetailFragmentDelegate, PAGSAdDelegate>
@property (nonatomic, weak) DetailFragmentPlatformView *owner;
- (instancetype)initWithOwner:(DetailFragmentPlatformView *)owner;
@end

@implementation DetailFragmentPlatformView

- (instancetype)initWithFrame:(CGRect)frame
               viewIdentifier:(int64_t)viewId
                    arguments:(id _Nullable)args
              binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
    self = [super init];
    if (self) {
        _viewId = viewId;
        [FlutterPanglePlugin logText:@"[DetailFragment] init viewId:%lld args:%@", viewId, args];
        _containerView = [[UIView alloc] initWithFrame:frame];
        _containerView.backgroundColor = [UIColor blackColor];
        
        // EventChannel per view
        NSString *eventChannelName = [NSString stringWithFormat:@"flutter_pangle/detail_fragment_events_%lld", viewId];
        _eventChannel = [FlutterEventChannel eventChannelWithName:eventChannelName
                                                   binaryMessenger:messenger];
        [_eventChannel setStreamHandler:self];
        
        // MethodChannel per view
        NSString *methodChannelName = [NSString stringWithFormat:@"flutter_pangle/detail_fragment_methods_%lld", viewId];
        _methodChannel = [FlutterMethodChannel methodChannelWithName:methodChannelName
                                                      binaryMessenger:messenger];
        __weak typeof(self) weakSelf = self;
        [_methodChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
            [weakSelf handleMethodCall:call result:result];
        }];
        
        // Parse arguments
        NSDictionary *params = [args isKindOfClass:[NSDictionary class]] ? args : nil;
        NSString *shortplayJson = nil;
        BOOL playSingleItem = YES;
        int initialPlayIndex = 1;
        BOOL autoPlay = NO;
        
        if (params) {
            id jsonObj = params[@"shortplay_json"];
            if ([jsonObj isKindOfClass:[NSString class]]) {
                shortplayJson = (NSString *)jsonObj;
            }
            
            id playSingleItemObj = params[@"play_single_item"];
            if ([playSingleItemObj isKindOfClass:[NSNumber class]]) {
                playSingleItem = [(NSNumber *)playSingleItemObj boolValue];
            }
            
            id indexObj = params[@"initial_play_index"];
            if ([indexObj isKindOfClass:[NSNumber class]]) {
                initialPlayIndex = MAX(0, [(NSNumber *)indexObj intValue]);
            }
            
            id autoPlayObj = params[@"auto_play"];
            if ([autoPlayObj isKindOfClass:[NSNumber class]]) {
                autoPlay = [(NSNumber *)autoPlayObj boolValue];
            }
        }
        
        _shouldAutoPlay = autoPlay;
        _playSingleItemMode = playSingleItem;
        _hasSetCurrentFragment = NO;
        [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld playSingleItem:%d autoPlay:%d initialIndex:%d jsonLength:%lu",
              viewId, playSingleItem, autoPlay, initialPlayIndex, (unsigned long)(shortplayJson.length)];
        _pendingSeekSeconds = nil;
        _pendingStartIndex = nil;
        _pendingSetCurrent = nil;
        _pendingPlayRequest = NO;
        _pendingPauseRequest = NO;
        _destroyed = NO;
        
        // 将JSON解析和Fragment创建移到后台线程，避免阻塞主线程
        // 但UI操作必须在主线程执行
        // 注意：weakSelf已经在第38行定义，这里直接使用
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 在后台线程解析JSON和创建对象
            PAGSShort *shortPlay = nil;
            if (shortplayJson && shortplayJson.length > 0) {
                shortPlay = [FlutterPanglePlugin convertMapToShort:shortplayJson];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld converted shortPlay:%@", viewId, shortPlay ? @(shortPlay.shortplay_id) : @"nil"];
            }
            
            // Create config
            PAGSDetailPageConfig *config = [PAGSDetailPageConfig customConfig];
            [config setHideLeftTopCloseAndTitle:YES clickAction:nil];
            [config displayTextVisibility:NO position:PAGSPlayviewpositionBottomDesc];
            [config displayTextVisibility:NO position:PAGSPlayviewpositionBottomTitle];
            [config setPlaySingleItem:playSingleItem];
            [config setStartPlayIndex:initialPlayIndex];
            [config displayProgressBar:NO];
            [config displayBottomExtraView:NO];
            [config setVideoScalingMode:PAGSVideoScalingModeAspectFill];
            //PAGSVideoScalingModeAspectFill 居中展示，会截取画面
            //PAGSVideoScalingModeAspectFit 按照屏幕居中展示，不够会有黑边
            //PAGSVideoScalingModeNone 按照屏幕居中展示，不够会有黑边
            //PAGSVideoScalingModeFill 全屏画面拉升
            
            [config setDefaultCoverImageContentMode:UIViewContentModeScaleAspectFill];
            
            // Load play icon image from plugin bundle and resize to 52x52
            NSBundle *pluginBundle = [NSBundle bundleForClass:[DetailFragmentPlatformView class]];
            UIImage *playIcon = [UIImage imageNamed:@"play" inBundle:pluginBundle compatibleWithTraitCollection:nil];
            if (!playIcon) {
                // Fallback to main bundle if not found in plugin bundle
                playIcon = [UIImage imageNamed:@"play"];
            }
            if (playIcon) {
                // Resize image to 52x52 pixels
                CGSize targetSize = CGSizeMake(52, 52);
                UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0);
                [playIcon drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];
                UIImage *resizedIcon = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
                
                [config setStartPlayIconImage:resizedIcon];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld setStartPlayIconImage success (52x52)", viewId];
            } else {
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld play icon not found", viewId];
            }
            
            // 回到主线程创建Fragment和UI
            // 使用dispatch_async确保在下一个runloop执行，避免阻塞当前初始化流程
            dispatch_async(dispatch_get_main_queue(), ^{
                __strong typeof(weakSelf) strongSelf = weakSelf;
                if (!strongSelf) return;
                
                // 延迟创建Fragment，避免阻塞主线程
                // 使用dispatch_after确保在下一个runloop执行
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    __strong typeof(weakSelf) strongSelf2 = weakSelf;
                    if (!strongSelf2) return;
                    
                    // Create detail fragment via plugin manager
                    PAGSDetailFragment *fragment = nil;
                    if (!strongSelf2.delegateWrapper) {
                        strongSelf2.delegateWrapper = [[DetailFragmentDelegateWrapper alloc] initWithOwner:strongSelf2];
                    } else {
                        strongSelf2.delegateWrapper.owner = strongSelf2;
                    }
                    if (shortPlay) {
                        fragment = [FlutterPanglePlugin createFragmentForViewId:strongSelf2.viewId
                                                                           short:shortPlay
                                                                          config:config
                                                                        delegate:strongSelf2.delegateWrapper];
                        [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld create fragment:%p shortId:%@", strongSelf2.viewId, fragment, @(shortPlay.shortplay_id)];
                    } else {
                        fragment = [FlutterPanglePlugin fragmentForViewId:strongSelf2.viewId];
                        [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld reuse fragment:%p", strongSelf2.viewId, fragment];
                        if (fragment) {
                            if ([fragment respondsToSelector:@selector(setDelegate:)]) {
                                [fragment performSelector:@selector(setDelegate:) withObject:strongSelf2.delegateWrapper];
                            } else if ([fragment respondsToSelector:@selector(updateDelegate:)]) {
                                [fragment performSelector:@selector(updateDelegate:) withObject:strongSelf2.delegateWrapper];
                            }
                        }
                    }
                    strongSelf2.detailFragment = fragment;
                    
                    // Get play view and add to container
                    UIView<PAGSPPlayerViewProtocol> *playView = [strongSelf2.detailFragment playView];
                    if (playView) {
                        playView.frame = strongSelf2.containerView.bounds;
                        playView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
                        [strongSelf2.containerView addSubview:playView];
                        [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld add playView:%p", strongSelf2.viewId, playView];
                    } else {
                        [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld playView nil", strongSelf2.viewId];
                    }

                    [strongSelf2 flushPendingCommands];
                    
                    // 在PageView场景下（playSingleItem为YES），需要预加载视频
                    // 注意：不在这里自动播放，播放应该由Flutter端通过play()方法控制
                    // 这样可以避免PageView预加载的多个页面同时尝试播放
                    if (strongSelf2.playSingleItemMode) {
                        // 预加载视频，延迟一点时间确保Fragment完全初始化
                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                            if (strongSelf2.detailFragment) {
                                [strongSelf2.detailFragment preLoadVideo];
                                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld preLoadVideo called", strongSelf2.viewId];
                            }
                        });
                    } else if (strongSelf2.shouldAutoPlay) {
                        // 非PageView场景，如果autoPlay为true，自动开始播放
                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                            if (strongSelf2.detailFragment) {
                                [strongSelf2.detailFragment startPlay];
                                    [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld auto startPlay", strongSelf2.viewId];
                            }
                        });
                    }
                });
            });
        });
    }
    return self;
}

- (UIView *)view {
    return _containerView;
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
    if (self.destroyed) {
        result(nil);
        return;
    }
    NSString *method = call.method;
    [FlutterPanglePlugin logText:@"[DetailFragment] handleMethodCall %@ viewId:%lld args:%@", method, self.viewId, call.arguments];
    
    if ([@"seekToSeconds" isEqualToString:method]) {
        NSNumber *secondsObj = call.arguments[@"seconds"];
        long seconds = secondsObj ? MAX(0, [secondsObj longValue]) : 0;
        if (!self.detailFragment) {
            self.pendingSeekSeconds = @(seconds);
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld pending seekToSeconds:%ld", self.viewId, seconds];
            result(nil);
            return;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.detailFragment setCurrentPlayTimeSeconds:seconds];
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld seekToSeconds:%ld", self.viewId, seconds];
            result(nil);
        });
    } else if ([@"pausePlay" isEqualToString:method]) {
        if (!self.detailFragment) {
            self.pendingPauseRequest = YES;
            self.pendingPlayRequest = NO;
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld pending pausePlay", self.viewId];
            result(nil);
            return;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // 在单集播放模式下，暂停时设置setCurrentFragment:NO
            if (self.playSingleItemMode) {
                [self.detailFragment setCurrentFragment:NO];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld setCurrentFragment:NO (pause)", self.viewId];
            }
            [self.detailFragment pausePlay];
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld pausePlay", self.viewId];
            result(nil);
        });
    } else if ([@"startPlay" isEqualToString:method]) {
        if (!self.detailFragment) {
            self.pendingPlayRequest = YES;
            self.pendingPauseRequest = NO;
            if (self.playSingleItemMode) {
                self.pendingSetCurrent = @(YES);
            }
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld pending startPlay", self.viewId];
            result(nil);
            return;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // 在单集播放模式下，开始播放时自动设置setCurrentFragment:YES
            if (self.playSingleItemMode) {
                [self.detailFragment setCurrentFragment:YES];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld setCurrentFragment:YES (startPlay)", self.viewId];
            }
            // 确保preLoadVideo完成后再播放，延迟一点时间
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                if (self.detailFragment) {
                    [self.detailFragment startPlay];
                    [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld invoke startPlay", self.viewId];
                }
            });
            result(nil);
        });
    } else if ([@"setVideoSpeed" isEqualToString:method]) {
        NSNumber *speedObj = call.arguments[@"speed"];
        float speed = speedObj ? [speedObj floatValue] : 1.0f;
        // Note: iOS SDK may not have direct speed control, implement if available
        result(nil);
    } else if ([@"startPlayIndex" isEqualToString:method]) {
        NSNumber *indexObj = call.arguments[@"index"];
        int index = indexObj ? MAX(0, [indexObj intValue]) : 0;
        if (!self.detailFragment) {
            self.pendingStartIndex = @(index);
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld pending startPlayIndex:%d", self.viewId, index];
            result(nil);
            return;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // 在单集播放模式下，开始播放时自动设置setCurrentFragment:YES
            if (self.playSingleItemMode) {
                [self.detailFragment setCurrentFragment:YES];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld setCurrentFragment:YES (startPlayIndex:%d)", self.viewId, index];
            }
            [self.detailFragment startPlayIndex:index];
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld startPlayIndex:%d", self.viewId, index];
            result(nil);
        });
    } else if ([@"setCurrentFragment" isEqualToString:method]) {
        // 保留此方法以兼容旧代码，但不推荐使用
        // 建议使用startPlay/pausePlay，它们会自动处理setCurrentFragment
        NSNumber *isCurrentObj = call.arguments[@"isCurrent"];
        BOOL isCurrent = isCurrentObj ? [isCurrentObj boolValue] : NO;
        if (!self.detailFragment) {
            self.pendingSetCurrent = @(isCurrent);
            if (isCurrent) {
                self.pendingPlayRequest = YES;
                self.pendingPauseRequest = NO;
            } else {
                self.pendingPauseRequest = YES;
                self.pendingPlayRequest = NO;
            }
            [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld pending setCurrentFragment:%d", self.viewId, isCurrent];
            result(nil);
            return;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.detailFragment setCurrentFragment:isCurrent];
            if (isCurrent) {
                [self.detailFragment startPlay];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld setCurrentFragment:YES -> startPlay", self.viewId];
            } else {
                [self.detailFragment stopPlay];
                [FlutterPanglePlugin logText:@"[DetailFragment] viewId:%lld setCurrentFragment:NO -> stopPlay", self.viewId];
            }
            result(nil);
        });
    } else {
        result(FlutterMethodNotImplemented);
    }
}

#pragma mark - FlutterStreamHandler

- (FlutterError *_Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(FlutterEventSink)events {
    self.eventSink = events;
    return nil;
}

- (FlutterError *_Nullable)onCancelWithArguments:(id _Nullable)arguments {
    self.eventSink = nil;
    return nil;
}

#pragma mark - PAGSDetailFragmentDelegate

- (BOOL)handleShortPlay:(PAGSShort *)shortPlay needBlockAtIndex:(int)index {
    if (self.destroyed) {
        return NO;
    }
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate needBlock viewId:%lld index:%d", self.viewId, index];
    [self emit:@"isNeedBlock" data:@{
        @"shortPlay": shortPlay,
        @"position": @(index)
    }];
    return NO;
}

- (void)handleShortPlay:(PAGSShort *)shortPlay showAdIfNeedAtIndex:(int)index unlockListener:(PAGSPlayBlockResultListener *)listener {
    if (self.destroyed) {
        return;
    }
    [FlutterPanglePlugin logText:@"syq-showAdIfNeedAtIndex"];
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate showAdIfNeed viewId:%lld index:%d", self.viewId, index];
    [self emit:@"showAdIfNeed" data:@{
        @"shortPlay": shortPlay,
        @"position": @(index)
    }];
}

- (void)handleShortPlay:(PAGSShort *)shortPlay playStartIndex:(int)index {
    if (self.destroyed) {
        return;
    }
    [FlutterPanglePlugin logText:@"syq-playStartIndex"];
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate playStartIndex viewId:%lld index:%d", self.viewId, index];
    [self emit:@"onShortPlayPlayed" data:@{
        @"shortPlay": shortPlay,
        @"position": @(index)
    }];
}

- (void)handleShortPlay:(PAGSShort *)shortPlay itemSelectedWithPosition:(NSInteger)position type:(PAGSFragmentItemType)type {
    if (self.destroyed) {
        return;
    }
    [FlutterPanglePlugin logText:@"syq-itemSelectedWithPosition"];
    [self emit:@"onItemSelected" data:@{
        @"position": @(position),
        @"itemType": @(type),
        @"subType": @0
    }];
}

- (BOOL)handlePlayFailed:(NSError *)error {
    if (self.destroyed) {
        return NO;
    }
    [FlutterPanglePlugin logText:@"syq-detailFragmentPlayFailed:%@",error.localizedDescription];
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate playFailed viewId:%lld error:%@", self.viewId, error];
    [self emit:@"onPlayFailed" data:@{
        @"error": error.localizedDescription ?: @"Unknown error"
    }];
    return NO;
}

- (void)handleShortPlay:(PAGSShort *)shortPlay playStateChanged:(PAGSPlayBackState)state index:(int)index {
    if (self.destroyed) {
        return;
    }
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate playStateChanged viewId:%lld state:%ld index:%d", self.viewId, (long)state, index];
    [self emit:@"onVideoPlayStateChanged" data:@{
        @"shortPlay": shortPlay,
        @"state": @(state),
        @"extra": @0
    }];
}

- (void)handleShortPlay:(PAGSShort *)shortPlay loadStateDidChanged:(PAGSLoadState)loadState index:(int)index {
    if (self.destroyed) {
        return;
    }
    // 加载状态改变时发送事件
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate loadState viewId:%lld loadState:%ld index:%d", self.viewId, (long)loadState, index];
    [self emit:@"onLoadStateChanged" data:@{
        @"shortPlay": shortPlay,
        @"loadState": @(loadState),
        @"position": @(index)
    }];
}

- (void)handleShortPlay:(PAGSShort *)shortPlay progressChanged:(long)currentPlayTime duration:(long)duration index:(int)index {
    if (self.destroyed) {
        return;
    }
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate progress viewId:%lld progress:%ld duration:%ld index:%d", self.viewId, currentPlayTime, duration, index];
    [self emit:@"onProgressChange" data:@{
        @"shortPlay": shortPlay,
        @"position": @(index),
        @"progress": @(currentPlayTime),
        @"duration": @(duration)
    }];
}

- (void)handleShortPlay:(PAGSShort *)shortPlay playFinishAtIndex:(int)index {
    if (self.destroyed) {
        return;
    }
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate playFinish viewId:%lld index:%d", self.viewId, index];
    [self emit:@"onVideoPlayCompleted" data:@{
        @"shortPlay": shortPlay,
        @"position": @(index)
    }];
}

- (void)handleShortPlayEnterImmersiveMode:(PAGSShort *)shortPlay {
    [self emit:@"onEnterImmersiveMode" data:nil];
}

- (void)handleShortPlayExitImmersiveMode:(PAGSShort *)shortPlay {
    [self emit:@"onExitImmersiveMode" data:nil];
}

- (void)handleShortPlay:(PAGSShort *)shortPlay onVideoInfoFetched:(PAGSPlayerInfo *)info index:(int)index {
    [FlutterPanglePlugin logText:@"syq-detailFragmentShortPlay:%@",info.description];
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate videoInfo viewId:%lld index:%d info:%@", self.viewId, index, info];
    NSMutableDictionary *data = [NSMutableDictionary dictionary];
    data[@"shortPlay"] = shortPlay;
    data[@"position"] = @(index);
    if (info) {
        data[@"videoInfo"] = @"Video info available";
    }
    [self emit:@"onVideoInfoFetched" data:data];
}

- (void)handleShortPlayDestroy:(PAGSShort *)shortPlay {
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate destroy viewId:%lld", self.viewId];
    [self emit:@"disposed" data:nil];
    self.destroyed = YES;
    self.pendingSetCurrent = nil;
    self.pendingStartIndex = nil;
    self.pendingSeekSeconds = nil;
    self.pendingPauseRequest = NO;
    self.pendingPlayRequest = NO;
    self.eventSink = nil;
    self.detailFragment = nil;
    self.delegateWrapper.owner = nil;
}

- (void)handleOverScroll:(PAGSScrollEvent)position {
    [FlutterPanglePlugin logText:@"[DetailFragment] delegate overScroll viewId:%lld position:%ld", self.viewId, (long)position];
    [self emit:@"onOverScroll" data:@{
        @"offset": @(position)
    }];
}

#pragma mark - Helper Methods

- (void)emit:(NSString *)event data:(NSDictionary *_Nullable)data {
    if (!self.eventSink || self.destroyed) return;
    [FlutterPanglePlugin logText:@"[DetailFragment] emit event:%@ viewId:%lld dataKeys:%@", event, self.viewId, data.allKeys];
    // 在后台线程执行convertShortToMap等耗时操作，避免阻塞主线程
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSMutableDictionary *payload = [NSMutableDictionary dictionary];
        payload[@"event"] = event;
        if (data) {
            // 如果data中包含shortPlay对象，需要转换
            NSMutableDictionary *processedData = [NSMutableDictionary dictionaryWithDictionary:data];
            id shortPlayObj = data[@"shortPlay"];
            if (shortPlayObj && [shortPlayObj isKindOfClass:[PAGSShort class]]) {
                processedData[@"shortPlay"] = [FlutterPanglePlugin convertShortToMap:(PAGSShort *)shortPlayObj] ?: @{};
            }
            payload[@"data"] = processedData;
        } else {
            payload[@"data"] = data;
        }
        // 回到主线程发送事件
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if (strongSelf && strongSelf.eventSink) {
                strongSelf.eventSink(payload);
            }
        });
    });
}

- (void)dealloc {
    [FlutterPanglePlugin logText:@"[DetailFragment] dealloc viewId:%lld", self.viewId];
    if (_detailFragment) {
        @try {
            [_detailFragment setCurrentFragment:NO];
        } @catch (NSException *exception) {
            [FlutterPanglePlugin logText:@"[DetailFragment] setCurrentFragment:NO failed viewId:%lld exception:%@", self.viewId, exception];
        }
        [_detailFragment pausePlay];
        @try {
            if ([_detailFragment respondsToSelector:@selector(setDelegate:)]) {
                [_detailFragment performSelector:@selector(setDelegate:) withObject:nil];
            } else if ([_detailFragment respondsToSelector:@selector(updateDelegate:)]) {
                [_detailFragment performSelector:@selector(updateDelegate:) withObject:nil];
            }
        } @catch (NSException *exception) {
            [FlutterPanglePlugin logText:@"[DetailFragment] clear delegate failed viewId:%lld exception:%@", self.viewId, exception];
        }
    }
    [FlutterPanglePlugin removeFragmentForViewId:self.viewId];
    _detailFragment = nil;
    _destroyed = YES;
    _eventSink = nil;
    _delegateWrapper.owner = nil;
    _delegateWrapper = nil;
}

- (void)flushPendingCommands {
    if (!self.detailFragment || self.destroyed) {
        return;
    }
    if (self.pendingSetCurrent) {
        BOOL isCurrent = [self.pendingSetCurrent boolValue];
        self.pendingSetCurrent = nil;
        [FlutterPanglePlugin logText:@"[DetailFragment] flush pending setCurrentFragment:%d viewId:%lld", isCurrent, self.viewId];
        [self.detailFragment setCurrentFragment:isCurrent];
    }
    if (self.pendingStartIndex) {
        int index = [self.pendingStartIndex intValue];
        self.pendingStartIndex = nil;
        [FlutterPanglePlugin logText:@"[DetailFragment] flush pending startPlayIndex:%d viewId:%lld", index, self.viewId];
        [self.detailFragment startPlayIndex:index];
    }
    if (self.pendingSeekSeconds) {
        long seconds = [self.pendingSeekSeconds longValue];
        self.pendingSeekSeconds = nil;
        [FlutterPanglePlugin logText:@"[DetailFragment] flush pending seekToSeconds:%ld viewId:%lld", seconds, self.viewId];
        [self.detailFragment setCurrentPlayTimeSeconds:seconds];
    }
    if (self.pendingPlayRequest) {
        self.pendingPlayRequest = NO;
        [FlutterPanglePlugin logText:@"[DetailFragment] flush pending play viewId:%lld", self.viewId];
        [self.detailFragment startPlay];
    }
    if (self.pendingPauseRequest) {
        self.pendingPauseRequest = NO;
        [FlutterPanglePlugin logText:@"[DetailFragment] flush pending pause viewId:%lld", self.viewId];
        [self.detailFragment pausePlay];
    }
}

@end

@implementation DetailFragmentDelegateWrapper

- (instancetype)initWithOwner:(DetailFragmentPlatformView *)owner {
    self = [super init];
    if (self) {
        _owner = owner;
    }
    return self;
}

- (BOOL)detailFragmentShortPlay:(PAGSShort *)shortPlay needBlockAtIndex:(int)index {
    if (!self.owner) { return NO; }
    return [self.owner handleShortPlay:shortPlay needBlockAtIndex:index];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay showAdIfNeedAtIndex:(int)index unlockListener:(PAGSPlayBlockResultListener *)listener {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay showAdIfNeedAtIndex:index unlockListener:listener];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay playStartIndex:(int)index {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay playStartIndex:index];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay itemSelectedWithPosition:(NSInteger)position type:(PAGSFragmentItemType)type {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay itemSelectedWithPosition:position type:type];
}

- (BOOL)detailFragmentPlayFailed:(NSError *)error {
    if (!self.owner) { return NO; }
    return [self.owner handlePlayFailed:error];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay playStateChanged:(PAGSPlayBackState)state index:(int)index {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay playStateChanged:state index:index];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay loadStateDidChanged:(PAGSLoadState)loadState index:(int)index {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay loadStateDidChanged:loadState index:index];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay progressChanged:(long)currentPlayTime duration:(long)duration index:(int)index {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay progressChanged:currentPlayTime duration:duration index:index];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay playFinishAtIndex:(int)index {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay playFinishAtIndex:index];
}

- (void)detailFragmentShortPlayEnterImmersiveMode:(PAGSShort *)shortPlay {
    if (!self.owner) { return; }
    [self.owner handleShortPlayEnterImmersiveMode:shortPlay];
}

- (void)detailFragmentShortPlayExitImmersiveMode:(PAGSShort *)shortPlay {
    if (!self.owner) { return; }
    [self.owner handleShortPlayExitImmersiveMode:shortPlay];
}

- (void)detailFragmentShortPlay:(PAGSShort *)shortPlay onVideoInfoFetched:(PAGSPlayerInfo *)info AtIndex:(int)index {
    if (!self.owner) { return; }
    [self.owner handleShortPlay:shortPlay onVideoInfoFetched:info index:index];
}

- (void)detailFragmentShortPlayDestroy:(PAGSShort *)shortPlay {
    if (!self.owner) { return; }
    [self.owner handleShortPlayDestroy:shortPlay];
}

- (void)detailFragmentOnOverScroll:(PAGSScrollEvent)position {
    if (!self.owner) { return; }
    [self.owner handleOverScroll:position];
}

@end

